Motivācija: Žūrnālfaili faktiski ir vislabākais informācijas avots par sistēmu darbību. Žurnālfailu apstrāde ir viena no vērtīgākajām prasmēm IS pārvaldībā. Un tad vēl tas NIS2... ;-) Varam ķert kļūdas un varam noteikt, vai kāds nesnaikstās (vai drizāk - cik daudz snaikstās) gar mūsu “durvīm” u.tml.
Owrt rūteri jau labu laiku ir manu personīgo tīklu pamatā. Tam nesen pievienojās OMV(openmediavault) serveri. Tā nu radās doma tiem likt sadarboties žurnalēšanas apstrādē.
Nepieciešamās priekšzināšanas: Linux, OWRT, OMV, Docker-Compose, Tīklošana...
Pamatdideja OWRT žurnalēšanai: OWRT -> Syslogd -> Grafana-Alloy -> Loki -> Grafana
Sākumā sagatavojam rsyslog konteineri. Iekš openmediavault omvextras tas izskatās sekojoši: Dockerfile:
version: "3.8" # Specify a version (recommended)
networks:
loki:
services:
rsyslogd:
# image: rsyslogd-image
image: rsyslog/syslog_appliance_alpine:latest
ports:
# Expose the syslog port (UDP) - or 514/tcp if needed
- "514:514/udp"
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TIME_ZONE}
volumes:
# Named volume for logs
- ${RSYSLOG_CONFIG_DIR}:/etc
- ${OPENWRT_LOGS_DIR}:/var/log
un atbilsošais env faila saturs:
RSYSLOG_CONFIG_DIR=/srv/jūsu_openmediavault_diska_identifikators_vai_share/grafana/rsyslog_config
OPENWRT_LOGS_DIR=/srv/jūsu_openmediavault_diska_identifikators_vai_share/grafana/openwrt_logs
PUID=1005
PGID=1006
TIME_ZONE=Europe/Riga
Ievēro: OMV (openmediavault) gadījumā un vispār dokera konteineru gadījumā japārliecinās, ka dokera konteineru lietotājiem ir atbilstošās saimniekdatora piesaistīto mapju un failu rakstīšanas tiesības. Skat. OMV
Piesaistītajā datņu mapē (RSYSLOG_CONFIG_DIR) izveidojam rsyslog.conf:
# rsyslog.conf (Main configuration file - /etc/rsyslog.conf inside container)
module(load="imudp") # For UDP syslog reception (or imtcp for TCP)
input(type="imudp" port="514") # Listen on the default syslog port (514)
# Include configuration files from the rsyslog.d directory
include(file="/etc/rsyslog.d/*.conf")
# $AllowedSender - specifies which remote systems are allowed to send syslog messages to rsyslogd
# Šeit ieraksta, vai nu atļaujos adrešu apgabalus, vai konkrētas adreses
$AllowedSender UDP, 192.168.1.0/24, [::1]/128, kaads.mans.server, *.mans.domens
# Izslēdzu jo rsyslog IP addresi VPN gadījumā uzrāda, kā nākošu no cita/VPN adrešu apgabala / apkštīkla.
#Custom template to generate the log filename dynamically based on the client's IP address.
#$template RemoteLogs, "/var/log/servers/%FROMHOST-IP%/%PROGRAMNAME%.log"
$template RemoteLogs,"/var/log/servers/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteLogs
& ~
AllowSender attiecīgi samainam adresāciju atbilstoši jūsu OpenWRT un/vai tīkla adresācijai. Žurnālfailu atrašanās (/var/log/...) konteneru iekšpusē.
Ķerambedre: Ja ceram dabūt UDP logus no VPN tīkla, tad atkarībā no konfigurācijas izcelsmes IP adrese var nebūt gaidītā. Lai gan variet sasniegt datorus citā VPN tīkla adrešu apgabalā pēc tam atbilstošām adresēm, tad izejošā adrese var būt cita, ko jāskatās VPN konfigurācijā.
Ieriekšējā sadaļā konfigurācijā ir norāde, ka var iekļaut citas konfigurācijas, kas var būt noderīgi, dažādu žurnālfailu saņemšanai un pirmasptrādei. Šo pašu konfigurāciju faktiski var izmantot dažādu žurnālfailu saņemšanai. Iesākumā gan tas nav vajadzīgs pietiek ar galveno iepriekšējā sadaļā esošo rsyslog.conf
Šīnī brīdī palaižot konteneri un atbilstoši nokonfigurējot ārējos log piegādātājus (piemēram kādu OWRT rūteri, vai tml.), jau varam (un vajag... ;-) ) šo sadaļu notestēt un pārliecināties, ka log dati tiek piegādāti un parādās atbilstošajā mapēs. OWRT rūtera konfigurācijā atiecīgi norādam, ka žurnalēšana notiks nosūtot uz mūsu OMV servera.
Pēc netā esošajās info uzdūros receptēm, kur nākošajā logu apstrādes solī tiek izmantots Promtail, bet palasot dokumentāciju, izrādādās promtail ir depreciated. Skatamies aizvietotāju Grafana-Agent, bet arī tas izrādās ir depreciated, abiem gan vēl ir kādu gadu(s) uz priekšu uzturēšanas termiņš. Attiecīgi nonācām līdz pēdējam, kas ir Grafana-Alloy. Šeit gan sastopam tādu lietu, ko ir vērts pastudēt, lai ietu tālāk - LogQL (log query language)
Loki OMV vidē izmantojot ENV failu nepieciešama sekojoša rinda:
-config.expand-env=true
Tad Grafana + Loki + Alloy docker compose (yml) datnes sadaļa, kas darbojas OMV izskatās šādi:
version: "3.8" # Specify a version (recommended)
networks:
loki:
services:
alloy:
image: grafana/alloy:latest
environment:
- PUID=${PUID}
- PGID=${PGID}
ports:
- 12345:12345
volumes:
- ${GRAFANA_AGENT_CONFIG_DIR}:/etc/alloy
- ${OPENWRT_LOGS_DIR}:/tmp/app-logs/
command: run --server.http.listen-addr=0.0.0.0:12345 --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy
depends_on:
- loki
networks:
- loki
loki:
image: grafana/loki:main
environment:
- PUID=${PUID}
- PGID=${PGID}
ports:
- 3100:3100
volumes:
- ${LOKI_CONFIG_DIR}:/etc/loki
command:
-config.file=/etc/loki/local-config.yaml
-config.expand-env=true
networks:
- loki
grafana:
image: grafana/grafana:latest
environment:
- PUID=${PUID}
- PGID=${PGID}
ports:
- "3030:3000"
networks:
- loki
depends_on: # Ensure Loki is running before Grafana
- loki
un atbilstošais .env:
OPENWRT_LOGS_DIR=/srv/jūsu_openmediavault_diska_identifikators/grafana/openwrt_logs
GRAFANA_AGENT_CONFIG_DIR=/srv/jūsu_openmediavault_diska_identifikators/grafana/grafana_alloy_conf
LOKI_CONFIG_DIR=/srv/jūsu_openmediavault_diska_identifikators/grafana/loki_config
PUID=1005
PGID=1006
Pirms laižam šo gaisā, jāsakonfigurē Graffana-Alloy un Loki. OMV atbilstošajās izdalīto datņu mapēs nepieciešamas sekojošas datnes (skat docker comose yaml datni augstāk):
5. Loki Configuration (local-config.yaml):
# This is a complete configuration to deploy Loki backed by the filesystem.
# The index will be shipped to the storage via tsdb-shipper.
# Šo varam iesākumā vienkārības labad atslēgt,
# sakonfigurēsim vēlāk, kad šis strādās.
auth_enabled: false
limits_config:
allow_structured_metadata: true
volume_enabled: true
server:
http_listen_port: 3100
common:
ring:
instance_addr: 0.0.0.0
kvstore:
store: inmemory
replication_factor: 1
path_prefix: /tmp/loki
schema_config:
configs:
- from: 2020-05-15
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
storage_config:
tsdb_shipper:
active_index_directory: /tmp/loki/index
cache_location: /tmp/loki/index_cache
filesystem:
directory: /tmp/loki/chunks
pattern_ingester:
enabled: true
Piezīme par auth_enabled: false: Atkarībā no drošības prasībām un tehniskā risinājuma šo var arī atstāt. Piemēram: nodalītā virtuālajā lokalājā tīklā, kas nav nekam citam paredzēts. Bet jebkurā gadījumā tas uz paša atbildību un zināšanām... ;-)
local.file_match "applogs" {
path_targets = [{"__path__" = "/tmp/app-logs/servers/*/*.log"}]
sync_period = "5s"
}
loki.write "local_loki" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
loki.relabel "extract_labels" {
forward_to = [loki.process.add_new_label.receiver]
rule {
source_labels = ["filename"]
target_label = "server_name"
regex = "/tmp/app-logs/servers/(?P<server_name>.*)/.*\\.log"
replacement = "$1"
action = "replace"
}
rule {
source_labels = ["filename"]
target_label = "app_name"
regex = "/tmp/app-logs/servers/.+?/(?P<app_name>.*)\\.log"
replacement = "$1"
action = "replace"
}
}
loki.source.file "local_files" {
targets = local.file_match.applogs.targets
forward_to = [loki.relabel.extract_labels.receiver]
}
loki.process "add_new_label" {
stage.logfmt {
mapping = {
"extracted_level" = "level",
"extracted_logger" = "logger",
}
}
stage.labels {
values = {
"level" = "extracted_level",
"logger" = "extracted_logger",
}
}
forward_to = [loki.write.local_loki.receiver]
}
Ja visu esam pareizi salikuši, tad kontenerim vajadzētu veiksmīgi pārbaudīties ar check un palaisties ar up
Atkarībā no konteineru pārvaldības vēlmēm abus yaml un env failus var salikt vienā. Pēc palaišanas OMV gadījumā jau redzēsim vai visi servisi ir pacēlušies:
Ja būs kāda problēma un nebūs zaļais Up, ieselektējam konteineri un izmantojam tā žurnalēšnas info (logs and follow logs):
Ja viss ir veiksmīgi palaidies, tad varam pārbaudīt konteineru iekšējo konfigurāciju darbību.
Vispirms varam pārbaudīt Grafana-Alloy web saskarnē vai log faili lasās, transformējas un/vai transportējas:
Pēc tam pašā Grafanā vajadzētu veiksmīgi pievienoties Logi datu avotam:

Tagad iespējams, ka labs laiks kafijas pauzei. Atkarībā no kādus žurnalēšanas info saņemat un cik intensīvi darbojas Jūsu rūteris, iespējams, ka kādu brīdi jāpagaida, lai ienāktos kādi žurnalēšanas dati. Jebkurā gadījumā ar vairāk logiem varētu būt interesantāk strādāt:
Tālāk jau nedaudz cita tēma, kā darboties ar Grafana, bet pirmajos soļos varētu dabūt ko šādu:
Šeit tiek atfiltrētas žurnalētās kļūdas un redzama to dinamika. Atliek tikai rakt dziļāk...
References: * https://blog.raphaelpiccolo.com/fr/post/show/849 * https://www.youtube.com/watch?v=xtEppndO7F8&t=43s * https://github.com/grafana/loki-fundamentals/tree/intro-to-ingesting * https://killercoda.com/grafana-labs/course/loki/intro-to-ingest * https://signoz.io/guides/a-regex-in-query-in-grafana/ * https://community.grafana.com/t/grafana-agent-flow-get-label-from-part-of-file-path/111431/3